home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PCMania 48
/
PCMania CD48_1.iso
/
pcmania
/
mod48
/
pcx3.c
< prev
Wrap
C/C++ Source or Header
|
1994-07-08
|
5KB
|
281 lines
// Extractor de ficheros PCX. By Esteban Moreno Valdés
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <fcntl.h>
#include <process.h>
#include <alloc.h>
#include <io.h>
#include <string.h>
#include "intro.h"
BYTE far *fpointer;
BYTE far *st;
BYTE fichero[30],paleta[769];
WORD MAXX,MAXY;
struct {
WORD size;
BYTE test;
BYTE encoding;
WORD x1,y1,x2,y2;
WORD HR,VR;
WORD bpl;
BYTE planes;
BYTE paleta;
} PCX;
void apunta_ES(void);
void load_pcx(char nombre[]);
void set_video_mode(BYTE);
void put_image(void);
void cargar_paleta(void);
void get_data(void);
void enciende(void); // Enciende la paleta
void apaga(void); // Oscurece la paleta
void desactiva(void); // Pone todos los colores a 0
BYTE get_pixel(WORD,WORD);
void put_pixel(WORD,WORD,BYTE); // Pone un pixel en pantalla
WORD code(BYTE,BYTE); // Invierte el orden de dos bytes
// en un mismo Word
void load_pcx(char nombre[])
{
int handle;
unsigned bytes_read;
// Carga un PCX
if ( (_dos_open(nombre,O_RDONLY,&handle))!=0 ) {
printf("\nError : No se puede cargar el fichero especificado\n\n");
exit(0);
}
// Asigna memoria
PCX.size = (WORD)filelength(handle);
if ( (fpointer = (BYTE far *) farmalloc(PCX.size+2)) == NULL ) {
set_video_mode(0x3);
printf("\nError : No se puede asignar memoria correctamente.\n\n");
exit(0);
}
// Lee la imagen entera y la almacena en un puntero
_dos_read(handle,(BYTE far *) fpointer,PCX.size,&bytes_read);
// Cierra el fichero PCX
_dos_close(handle);
get_data();
desactiva();
put_image();
cargar_paleta();
farfree(fpointer);
}
void set_video_mode(BYTE modo)
{
asm {
xor ah,ah
mov al,modo
int 10h
}
}
void apunta_ES(void)
{
asm {
mov ax,0a000h
mov es,ax
}
}
void put_image(void)
{
BYTE get_byte,sb,i,i2,color;
WORD pdi=0,X=0,Y=0;
MAXX = PCX.x2 - PCX.x1 +1;
MAXY = PCX.y2 - PCX.y1 +1;
st=fpointer; // Guardo la dirección del puntero
fpointer+=128; // Un vez leída me salto la cabecera
while (Y <= MAXY) {
get_byte=*fpointer; // Cojo un byte
sb = get_byte & 192;
if (sb==192) { i = get_byte & 63; // Nº de veces que se repetirá
// el siguiente byte de la Img.
fpointer++;
color = *fpointer;
apunta_ES();
for (i2=1;i2<=i;i2++) {
pdi = (320 * Y) + X;
asm mov di,pdi
asm mov al,color
asm mov es:[di],al
X++;
if (X >= MAXX) { X=0; Y++; }
}
fpointer++; // Next byte
}
else { color = *fpointer;
apunta_ES();
pdi = (320 * Y) + X;
asm mov di,pdi
asm mov al,color
asm mov es:[di],al
X++;
if (X >= MAXX) { X=0; Y++; }
fpointer++; // Next byte
}
}
fpointer=st; // Recupero la antigua dirección del puntero
}
WORD code(BYTE lbyte,BYTE hbyte)
{
union REGS regs;
regs.h.al=*(fpointer+lbyte);
regs.h.ah=*(fpointer+hbyte);
return( regs.x.ax );
}
void cargar_paleta(void)
{
WORD index,adr=0;
fpointer=fpointer+(PCX.size-768);
for (index=0;index<=255;index++) {
*(fpointer+adr)=*(fpointer+adr)/4; adr++;
*(fpointer+adr)=*(fpointer+adr)/4; adr++;
*(fpointer+adr)=*(fpointer+adr)/4; adr++;
}
}
void desactiva(void)
{
WORD index;
for (index=0;index<=255;index++) {
outportb(0x3C8,index);
outportb(0x3C9,0);
outportb(0x3C9,0);
outportb(0x3C9,0);
}
}
void enciende(void)
{
BYTE r,g,b,r2,g2,b2;
WORD index,index2,adr=0;
for (index2=0;index2<=63;index2++) {
for (index=0;index<=255;index++) {
outportb(0x3C7,index);
r=inportb(0x3C9);
g=inportb(0x3C9);
b=inportb(0x3C9);
r2=*(fpointer+adr); adr++;
g2=*(fpointer+adr); adr++;
b2=*(fpointer+adr); adr++;
if (r<r2) r++;
if (g<g2) g++;
if (b<b2) b++;
outportb(0x3C8,index);
outportb(0x3C9,r);
outportb(0x3C9,g);
outportb(0x3C9,b);
}
adr=0;
}
}
void apaga(void)
{
BYTE r,g,b;
WORD index,index2,adr=0;
for (index2=0;index2<=63;index2++) {
for (index=0;index<=255;index++) {
outportb(0x3C7,index);
r=inportb(0x3C9);
g=inportb(0x3C9);
b=inportb(0x3C9);
if (r>0) r--;
if (g>0) g--;
if (b>0) b--;
outportb(0x3C8,index);
outportb(0x3C9,r);
outportb(0x3C9,g);
outportb(0x3C9,b);
}
}
}
void get_data(void)
{
PCX.test = *(fpointer);
PCX.encoding = *(fpointer+2);
PCX.planes = *(fpointer+65);
PCX.paleta = *(fpointer+(PCX.size-769));
PCX.HR = code(12,13);
PCX.VR = code(14,15);
PCX.x1 = code(4,5);
PCX.y1 = code(6,7);
PCX.x2 = code(8,9);
PCX.y2 = code(10,11);
PCX.bpl = code(66,67);
}
void put_pixel(WORD x,WORD y,BYTE color)
{
asm {
mov ax,y
mov bx,y
shl ax,8
shl bx,6
add ax,bx // Y * 320
mov di,x
add di,ax // Y * 320 + X
mov ax,0a000h
mov es,ax
mov al,color
mov es:[di],al
}
}
BYTE get_pixel(WORD x,WORD y)
{
BYTE color;
asm {
mov ax,y
mov bx,y
shl ax,8
shl bx,6
add ax,bx // Y * 320
mov di,x
add di,ax // Y * 320 + X
mov ax,0a000h
mov es,ax
mov al,es:[di]
mov color,al
}
return(color);
}